﻿using SDL2;
using System;

namespace BITUI
{
    class Program
    {


        static Tile.WriteableTile write;
        static void Main(string[] args)
        {
            var exepath = System.IO.Path.GetDirectoryName(typeof(Program).Assembly.Location);
            var curpath = System.IO.Directory.GetCurrentDirectory();

            System.Console.WriteLine("curpath =" + curpath);
            System.Console.WriteLine("exepath =" + exepath);

            System.IO.Directory.SetCurrentDirectory(exepath);
            //初始化模拟器
            nes.SimTool.Init();
            var b = nes.SimTool.LoadAndStartGame("kdxf.nes");




            //AudioTest
            //if (BITUI.AppFramework.AudioSystem.AudioInited)
            //{
            //    BITUI.AppFramework.AudioSystem.PlayBackgroundMusic("3.ogg");
            //}
            //Audio.BackgroundMusic music = null;
            //Audio.AudioChunk effect = null;




            //主窗口，資源跟著窗口走，兩個窗口不能共享Bank資源
            Window mainWindow = OpenWindow1();
            mainWindow.eventOnKey += (key, press) =>
            {
                if (key.scancode == SDL2.SDL.SDL_Scancode.SDL_SCANCODE_F1 && press)
                {
                    OpenWindow2();
                }
                if (key.scancode == SDL2.SDL.SDL_Scancode.SDL_SCANCODE_F2 && press)
                {
                    if (AppFramework.AudioSystem.AudioInited)
                    {
                        //AppFramework.AudioSystem.PlayChunk(effect);
                    }
                }
                if (key.scancode == SDL2.SDL.SDL_Scancode.SDL_SCANCODE_F3 && press)
                {
                    if (AppFramework.AudioSystem.AudioInited)
                    {
                        //AppFramework.AudioSystem.PlayBackgroundMusic(music, true, 2.0f);
                    }
                }

                var con = nes.SimTool.conP0;
                switch (key.scancode)
                {
                    case SDL.SDL_Scancode.SDL_SCANCODE_W:
                        con.bUp = press;
                        break;
                    case SDL.SDL_Scancode.SDL_SCANCODE_A:
                        con.bLeft = press;
                        break;
                    case SDL.SDL_Scancode.SDL_SCANCODE_S:
                        con.bDown = press;
                        break;
                    case SDL.SDL_Scancode.SDL_SCANCODE_D:
                        con.bRight = press;
                        break;
                    case SDL.SDL_Scancode.SDL_SCANCODE_J:
                        con.bBtnB = press;
                        break;
                    case SDL.SDL_Scancode.SDL_SCANCODE_K:
                        con.bBtnA = press;
                        break;
                    case SDL.SDL_Scancode.SDL_SCANCODE_O:
                        con.bBtnSelect = press;
                        break;
                    case SDL.SDL_Scancode.SDL_SCANCODE_P:
                        con.bBtnStart = press;
                        break;
                }
            };
            //这个主循环是在当前线程hold住的
            BITUI.AppFramework.MainLoop(mainWindow);

        }
        static Window OpenWindow1()
        {
            var option = WindowOption.Auto_Scale4X;
            option.title = "helloworld";
            option.tileWidth = 45;
            option.tileHeight = 30;
            option.linear = false;
            option.scale = 2.0F;
            option.scaleMode = WindowOption_ScaleMode.AutoTileCount;

            var win = BITUI.AppFramework.CreateWindow(option);

            //Bank是存放Tile的集合，一个Tile就是8x8像素的原始图块，Bank里的Tile是任意尺寸的（1~255不需要方形）
            //但是他们绘制到屏幕上时要8x8对齐
            //所以Bank既是图集，又是字库
            BITUI.Tile.TileTool.LoadASCII12toBank(win.GetBank(0)); //英文12点阵字库 ，8字库太小了
            BITUI.Tile.TileTool.LoadHZK12toBank(win.GetBank(0));//中文12点阵字库，中文能显示清楚12最合适


            var tile = win.GetBank(0).CreateTile("grid", BITUI.Tile.TileTool.GenGridTileData());
            var tile2 = win.GetBank(0).CreateTile("border1", BITUI.Tile.TileTool.GenOnePixelBorder(true, true, true, true, 0x35));
            var tile3 = win.GetBank(0).CreateTile("border2", BITUI.Tile.TileTool.GenTwoPixelBorder(true, true, true, true, 0x35));

            var scale9_1 = Tile.Scale9.CreateSingleBorderScale9(win.GetBank(0), "scale1");//单边框，代码生成的，不用图集
            var scale9_2 = Tile.Scale9.CreateTwoBorderScale9(win.GetBank(0), "scale2");//双边框,代码生成的，不用图集


            var rootSplit = new Element.SplitPanel();
            rootSplit.Fill = true;
            rootSplit.TileYLocal = 2;
            rootSplit.TileXLocal = 1;
            rootSplit.BorderRightLocal = 1;
            rootSplit.BorderBottomLocal = 1;
            win.RootElement = new Element.Canvas();
            win.RootElement.AddChild(rootSplit);

            var labelfps = new BITUI.Element.Label(win.GetBank(0), "fps=0") { TileXLocal = 0, TileYLocal = 0 };
            win.RootElement.AddChild(labelfps);

            var canvasPanel = rootSplit.panelA;
            canvasPanel.backGround = scale9_2;
            canvasPanel.backGroundColorReplace = 35;


            canvasPanel.AddChild(new BITUI.Element.Image(tile) { TileXLocal = 0, TileYLocal = 2, TileWidth = 5, TileHeight = 5, FillMode = true });

            canvasPanel.AddChild(new BITUI.Element.Image(tile2) { TileXLocal = 2, TileYLocal = 2 });
            canvasPanel.AddChild(new BITUI.Element.Image(tile3) { TileXLocal = 4, TileYLocal = 2 });

            canvasPanel.AddChild(new BITUI.Element.Label(win.GetBank(0), "Hello world!") { TileXLocal = 4, TileYLocal = 3 });

            canvasPanel.AddChild(new BITUI.Element.Label(win.GetBank(0), "武汉加油，中国很行！") { TileXLocal = 4, TileYLocal = 6, colorReplace = 0x28, TileWidth = 20, backGround = scale9_1, backGroundColorReplace = 0x35 });


            canvasPanel.AddChild(new BITUI.Element.Label(win.GetBank(0), "这是一个像素UI系统，为Dotnet Core 和 C# 编写") { TileXLocal = 4, TileYLocal = 8, backGround = scale9_1, backGroundColorReplace = 0x35 });
            canvasPanel.AddChild(new BITUI.Element.Label(win.GetBank(0), "使用SDL2开发，完全可以跨平台 windows linux macos等") { TileXLocal = 4, TileYLocal = 14, TileWidth = 35, backGround = scale9_1, HAlign = Element.HAlign.Right });
            canvasPanel.AddChild(new BITUI.Element.Label(win.GetBank(0), "支持多窗口 按F1再打开一个!") { TileXLocal = 4, TileYLocal = 18, TileHeight = 3, TileWidth = 30, backGround = scale9_2, backGroundColorReplace = 0x37 });


            var btn = new Element.Button();
            btn.TileXLocal = 4;
            btn.TileYLocal = 24;
            btn.stateNormal = new BITUI.Element.Label(win.GetBank(0), "button") { TileWidth = 6, TileHeight = 2, backGround = scale9_1, backGroundColorReplace = 0x38 };
            btn.statePointOver = new BITUI.Element.Label(win.GetBank(0), "button") { TileWidth = 6, TileHeight = 2, backGround = scale9_1, backGroundColorReplace = 0x30 };
            btn.statePress = new BITUI.Element.Label(win.GetBank(0), "button") { TileWidth = 6, TileHeight = 2, backGround = tile, backGroundColorReplace = 0x30 };
            canvasPanel.AddChild(btn);



            var input = new Element.InputBox(win.GetBank(0), "input here.");
            input.backGround = scale9_1;
            input.TileXLocal = 14;
            input.TileYLocal = 24;

            canvasPanel.AddChild(input);

            //准备模拟器显示区域
            {
                //创建一个可以写的特殊Tile,用来承接模拟器产生的画面
                write = win.CreateWriteableTile(Tile.TileTool.GetNesPalette(), 256, 240);


                var canvasNes = rootSplit.panelB;

                canvasNes.backGround = scale9_2;
                canvasNes.backGroundColorReplace = 0x3A;



                canvasNes.AddChild(new BITUI.Element.Image(write) { TileXLocal = 0, TileYLocal = 2 });

                //canvasPanel.AddChild(canvasNes);

            }


            win.eventOnUpdate += () =>
            {
                labelfps.text = "fps=" + AppFramework.Fps.ToString("F2");

                if (write != null)
                {
                    var pdata = nes.SimTool.pixel;
                    var srcpalette = nes.SimTool.palette;
                    //lock (pdata)
                    {
                        write.FixPixel((tile, memory, pitch) =>
                    {

                        unsafe
                        {
                            int* data = (int*)memory;
                            for (int y = 0; y < 240; y++)
                            {
                                for (int x = 0; x < 256; x++)
                                {
                                    var curaddr = y * (pitch / 4) + x;
                                    var srcaddr = y * 256 + x;
                                    data[curaddr] = srcpalette[pdata[srcaddr]];
                                }

                            }
                        }
                    });
                    }
                }
            };


            return win;
        }
        static void OpenWindow2()
        {
            var win2 = BITUI.AppFramework.CreateWindow("fixwin", 16, 4, WindowOption_ScaleMode.FixTileSize, false, 4.0f);

            //加载了字库才能显示文字
            BITUI.Tile.TileTool.LoadASCII12toBank(win2.GetBank(0));

            var tile2 = win2.GetBank(0).CreateTile("grid", BITUI.Tile.TileTool.GenGridTileData());
            win2.RootElement = new Element.Canvas();
            win2.RootElement.AddChild(new BITUI.Element.Image(tile2));
            win2.RootElement.AddChild(new BITUI.Element.Label(win2.GetBank(0), "Zoom Window！") { TileXLocal = 1, TileYLocal = 1 });

        }
    }
}
